package com.sys.basics.controller;

import cn.hutool.core.util.ArrayUtil;
import com.sys.basics.config.jsonRes.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

@ApiIgnore
@Slf4j
@RestController
public class MyGlobalErrorController implements ErrorController {

    private final static String ERROR_PATH = "/error";

    @Autowired
    private ErrorAttributes errorAttributes;

    private Map<String, Object> getErrorAttributes(HttpServletRequest request, ErrorAttributeOptions options) {
        ServletWebRequest servletWebRequest = new ServletWebRequest(request);
        return this.errorAttributes.getErrorAttributes(servletWebRequest, options);
    }

    @ResponseBody
    @RequestMapping(path = ERROR_PATH)
    public JsonResult error(HttpServletRequest request) {
        ErrorAttributeOptions options = ErrorAttributeOptions.defaults();
        Map<String, Object> errorBody = getErrorAttributes(request, options.including(ErrorAttributeOptions.Include.values()));

        StringBuilder errorString = new StringBuilder();
        // 可以不用, 启用MyGlobalExceptionHandler中的validationBodyException
        /*if(errorBody.get("exception").equals("org.springframework.web.bind.MethodArgumentNotValidException")) {
            Collection errorCollections = (Collection) errorBody.get("errors");
            List<ObjectError> errorList = new ArrayList(errorCollections);
            errorList.forEach(error -> {
                errorString.append(error.getDefaultMessage()).append(",");
            });
        }*/
        // 可以不用, 启用MyGlobalExceptionHandler中的validationPathException
        /*if(errorBody.get("exception").equals("javax.validation.ConstraintViolationException")){
            List errorList = Arrays.asList(errorBody.get("message").toString().split(","));
            errorList.forEach(error->{
                String[] arr = StringUtils.deleteWhitespace(error.toString()).split(":");
                errorString.append(arr[arr.length-1]).append(",");
            });
        }*/

        String message = StringUtils.isNotEmpty(errorString) ? errorString.toString().substring(0, errorString.lastIndexOf(",")) : errorBody.get("message").toString();

        log.info(">>>全局捕获到异常<<<：异常信息【{}】, 异常路径【{}】", message, errorBody.get("path"));

        Map<String, Object> data = new HashMap<>();
        data.put("timestamp",errorBody.get("timestamp"));
        data.put("error",errorBody.get("error"));
        data.put("exception",errorBody.get("exception"));
        data.put("trace",errorBody.get("trace"));
        data.put("path",errorBody.get("path"));
        data.put("message", message);

        JsonResult result = new JsonResult();
        result.setCode(errorBody.get("status").toString());
        result.setMessage(message);
        result.setData(data);
        return result;
    }

}